#include "socket.hpp"
#include <memory>
#include <iso646.h>
#include <iostream>
#include "TcpServer.hpp"
#include <thread>
#include "Protocol.hpp"
#include "calculator.hxx"
#include <cmath>
using namespace Protocol;



//下面处理步骤十分多，但是可以分为接受消息，处理消息，发送消息
///因此我们可以去封装一部分代码，专门提取出处理消息的代码
static std::function<void(std::shared_ptr<Net_TcpSocket:: Socket>)> HanderRequest= [](std::shared_ptr<Net_TcpSocket:: Socket> sockptr){
    std::string inbufferstream;
    std::unique_ptr<Factory> fcty = std::make_unique<Factory>();
    Calculator::Calculator cal; 
    auto req =  fcty->BuildRequest();
    auto resp = fcty->BuildReponse();
        while(1)
        {
            //读取报文
            if(!sockptr->Recv(&inbufferstream,1024))
            {
                //没有读取到就退出
                break;
            }
            //分析报文
            std::string msg;
            //有没可能读取了多个可解码的数据呢？
            //可能，因此下面应该是循环
            while(Decode(inbufferstream,&msg))
            {
                //到这里，有了完整的报文,处理报文

                //若是反序列化错误，先退出
                if(!req->Deserialize(msg)) break;
                

                //进行处理业务，也就是计算
                resp->SetResult(cal(std::to_string(req->GetX()) +req->GetOP()+std::to_string(req->GetY()) ));
                resp->SetCode(cal.ErrorCode());
                
                //之后进行序列化
                std::string send_string;
                resp->Serialisze(&send_string);

                //然后进行编码
                send_string = Encode(send_string);

                //发送
                sockptr->Send(send_string);
                
            }
            //没有读取完
            continue;
        }
    };



int main(int argc,char* argv[])
{
    if(argc != 2)
    {
        std::cout<<"Usage ./"<<argv[0]<<" port\n";
        return 0; 
    } 
    uint16_t localport = std::stoi(argv[1]);

    

    std::unique_ptr<TcpServer> svr(new TcpServer(localport,HanderRequest));
    svr->WorkLoop();
    return 0;
}